package com.fzy.core.webwork;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fzy.core.entity.EntityId;
import com.fzy.core.entity.EntityIdString;
import com.fzy.core.utils.U;
import com.opensymphony.webwork.interceptor.ServletRequestAware;
import com.opensymphony.webwork.interceptor.ServletResponseAware;
import com.opensymphony.webwork.util.TokenHelper;
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.ActionSupport;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class BaseAction extends ActionSupport implements ServletRequestAware, ServletResponseAware {
	private static final long serialVersionUID = 2925430793127104593L;
	private static final Logger log = LoggerFactory.getLogger(BaseAction.class);
	protected HttpServletRequest request;
	protected HttpServletResponse response;
	
	protected Map getRequestParams(){
		ActionContext context = ActionContext.getContext();
		Map requestParameters = (Map)context.getParameters();
		Map result = new HashMap();
		for (Iterator iterator = requestParameters.entrySet().iterator(); iterator.hasNext();) {
			Map.Entry entry = (Map.Entry) iterator.next();
			String[] value = (String[])entry.getValue();
			if(value != null && value.length > 0){
				result.put(entry.getKey(), value[0]);
			}
		}
		return result;
	}
	
	protected void validateToken() {
        Map session = ActionContext.getContext().getSession();
        synchronized (session) {
            if (!TokenHelper.validToken()) {
                addActionError(getText("error.duplicateSubmission"));
            }
        }
	}
	
	protected EntityId validateId(String idString, String clazz) {
		try {
			return validateIdAndGetEntity(idString, Class.forName(clazz));
		} catch (ClassNotFoundException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	protected EntityIdString validateIdStringAndGetEntity(String idString, Class clazz) {
		return validateIdStringAndGetEntity(idString, "id", clazz);
	}

	protected EntityIdString validateIdStringAndGetEntity(String idString, String idProperty, Class clazz) {
		Object entityObj = null;
		if (!StringUtils.isBlank(idString)) {
			idString = idString.trim();
				entityObj = U.getBaseService().getByIdString(clazz, idProperty, idString);
				if (entityObj == null) {
					addActionError(getText("error.entityMissing",
							new String[] { idString }));
				}
		}
		return (EntityIdString)entityObj;
	}

	/**校验录入动作对象是否存在，并返回对象
	 * @param idString
	 * @param clazz
	 * @return
	 */
	protected EntityId validateIdAndGetEntity(String idString, Class clazz) {
		Object entityObj = null;
		//id 不为空，才进行查询
		if (!StringUtils.isBlank(idString)) {
			Long id = null;
			// 若ID不是LONG型，则报错“idError”
			try {
				long i = Long.parseLong(idString.trim());
				id = new Long(i);
			} catch (NumberFormatException e) {
				addActionError(getText("error.idError",
						new String[] { idString }));
			}
			// 若根据正常的ID找不到对象，那报错“entityMissing”
			if (id != null) {
				entityObj = U.getBaseService().get(clazz, id);
				if (entityObj == null) {
					addActionError(getText("error.entityMissing",
							new String[] { idString }));
				}
			}
		}
		return (EntityId) entityObj;
	}
	
	protected Object newEntity(Class clazz){
		Object entityObj = null;
		try {
			entityObj = clazz.newInstance();
		} catch (InstantiationException e) {
			log.error(e.getMessage(), e);
		} catch (IllegalAccessException e) {
			log.error(e.getMessage(), e);
		}
		return entityObj;
	}
	
//	protected void validateSelectQuery(Class clazz){
//		String mode = request.getParameter("_m");
//		String selectValue = request.getParameter("_sv");
//		if("1".equals(mode) && !StringUtils.isBlank(selectValue)){
//			Object e = validateIdAndGetEntity(selectValue, clazz);
//			if(e == null){
//				log.error("Cannot find entity ["+clazz+"] by id ["+selectValue+"].");
//			}
//			if(e != null && e instanceof Display){
//				Display d = (Display)e;
//				String displayName = d.display();
//				request.setAttribute("_sv2", displayName == null ? "" : displayName);
//				selected = true;
//			}
//		}
//	}

	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
	
	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

//	public boolean isSelected() {
//		return selected;
//	}
	
	//下载方法
	protected void renderTemplate(HttpServletResponse response, Object model, String templateName,String fileName) throws Exception {
			
			HashMap m = new HashMap();
			m.put("m", model);
			
			// 取得要装载的模板
			Configuration configuration = new Configuration();
			// 模板编码
			configuration.setDefaultEncoding("UTF-8");
			// 模板路径
			configuration.setClassForTemplateLoading(BaseAction.class, "../../../../ftl");
			Template t = null;
			t = configuration.getTemplate(templateName);
			
			// 准备输出内容
			StringWriter tempWriter = new StringWriter();
			BufferedWriter bw = new BufferedWriter(tempWriter);
			t.process(m, bw);
			bw.flush();
			String text = tempWriter.toString();
			
			fileName = new String(fileName.getBytes("gb2312"), "ISO-8859-1");
			response.setHeader("Content-Disposition", "attachment; filename=\""+ fileName + "\";");
			
			// 输出，编码必须与模板编码一致，否则WORD文件损坏
			render(response, text, "application/vnd.ms-excel;charset=UTF-8");
		}

		/**
		 * 直接输出.
		 * 
		 * @param contentType 内容的类型.html,text,xml的值见后，json为"text/x-json;charset=UTF-8"
		 */
		protected void render(HttpServletResponse response, String text,
				String contentType) {
			try {
				response.setContentType(contentType);
				response.getWriter().write(text);
			} catch (IOException e) {
				log.error(e.getMessage(), e);
			}
		}
}
